
#include <stdio.h>
#include <string.h>
#include <strings.h>

extern int yylineno;    /* line number in file being parsed (from lex) */

#define MAX_EXCEPTIONS  10
#define MAX_ENTRIES     1024
#define MAX_NAME_LEN    64 
#define PARAM_LEN       130
#define MAX_REPEAT      2
#define MAX_CLASS       10
#define MAX_CONV        128
#define MAX_SETPT_CLASS 16

#define FALSE  0
#define TRUE   1

#define PAGE_BREAK    '\014'

char Error[80];   /* used by error routines in gram.y to call yyerror ! */
char Last_Entry_Name[MAX_NAME_LEN]; /* used in gram.y to remember the name of the last exception */

#define MIN(x,y) ((x<y)?x:y)
#define MAX(x,y) ((x>y)?x:y)

#include "cm.h"


int Num_Classes;
char Class_Names[MAX_CLASS][MAX_NAME_LEN];

int Num_Conv;
char Conv_Names[MAX_CONV][MAX_NAME_LEN];

int Num_Setpt_Classes;
char Setpt_Classes[MAX_SETPT_CLASS][MAX_NAME_LEN];

int Num_Repeat;
char Repeat_Names[MAX_REPEAT][MAX_NAME_LEN];



typedef struct { char  Name[MAX_NAME_LEN];
                 char  Msg_Name[ MAX_NAME_LEN ];
                 char  Status_Msg_Name[ MAX_NAME_LEN ];
                 char  Glp_Hdr_Msg [ MAX_NAME_LEN ];
                 char  Glp_Msg_Name[ MAX_NAME_LEN ];
                 char  Glp_Dev_Code[ MAX_NAME_LEN ];
                 int   Class;
                 int   Repeatable;
                 int   Conv;
                 int   Setpt_Class;
               } Entry;


typedef struct {
          char    Name[ MAX_NAME_LEN ];
          char    Type_Position[ MAX_NAME_LEN ];
          Entry   Entries[ MAX_ENTRIES ];
          int     Num_Entries;
          int     Use_Setpt_Rules;
          int     Base_Exception_No;
          Entry   Scrolling_Title_Entry;
        
       } EXCEPTION;

EXCEPTION Exceptions[MAX_EXCEPTIONS];
int       Num_Exceptions;


/* yyerror - called by yacc(1), lex(1), and mc to display errors */
void yyerror(char *s)
{
        (void)fprintf(stderr, "ERROR  (%u) %s\n", yylineno, s);
}

void CreateType(char *type, char *scrolling_title, char *type_position, char *base_exception_no)
{
   if ( Num_Exceptions < MAX_EXCEPTIONS )
   {
        strcpy ( Exceptions[Num_Exceptions].Name, type );
        UpshiftName( Exceptions[Num_Exceptions].Name );
        Exceptions[Num_Exceptions].Use_Setpt_Rules = FALSE;

        strcpy ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Name, type );
        strcat ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Name, "_PlaceHolder" );

        /* Store the type position */
        strcpy ( Exceptions[Num_Exceptions].Type_Position, type_position );
        UpshiftName( Exceptions[Num_Exceptions].Type_Position );

        /* Store the base exception number */
        Exceptions[Num_Exceptions].Base_Exception_No = atoi( base_exception_no );

        strcpy ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Glp_Hdr_Msg, "NO_MSG" );
        strcpy ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Msg_Name, "NO_MSG" );
        strcpy ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Glp_Msg_Name, "NO_MSG" );

        /* Store the type of title in the unused glp dev code */
        strcpy ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Glp_Dev_Code, type );
        strcat ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Glp_Dev_Code, "_CLASS" );

        Exceptions[Num_Exceptions].Scrolling_Title_Entry.Class = 0;
        Exceptions[Num_Exceptions].Scrolling_Title_Entry.Repeatable = 0;
        Exceptions[Num_Exceptions].Scrolling_Title_Entry.Conv = 0;

        strcpy ( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Status_Msg_Name, scrolling_title );
        UpshiftName( Exceptions[Num_Exceptions].Scrolling_Title_Entry.Status_Msg_Name );
 
        Num_Exceptions++;
   }
}


void CreateSetptType( char *type )
{
   if ( Num_Exceptions < MAX_EXCEPTIONS )
   {
        strcpy ( Exceptions[Num_Exceptions].Name, type );
        UpshiftName( Exceptions[Num_Exceptions].Name );
        Exceptions[Num_Exceptions].Use_Setpt_Rules = TRUE;

        Num_Exceptions++;
   }
}


void CreateRepeat( char *type )
{
   if ( Num_Repeat < MAX_REPEAT )
   {
        strcpy ( Repeat_Names[Num_Repeat], type );
        UpshiftName( Repeat_Names[Num_Repeat] );
        Num_Repeat++;
   }
}


void CreateClass( char *type )
{
   if ( Num_Classes < MAX_CLASS )
   {
        strcpy ( Class_Names[Num_Classes], type );
        UpshiftName( Class_Names[Num_Classes] );
        Num_Classes++;
   }
}


void CreateConv( char *type )
{
   if ( Num_Conv < MAX_CONV )
   {
        strcpy ( Conv_Names[Num_Conv], type );
        UpshiftName( Conv_Names[Num_Conv] );
        Num_Conv++;
   }
}

void CreateSetptClass( char *class )
{
   if ( Num_Setpt_Classes < MAX_SETPT_CLASS )
   {
        strcpy ( Setpt_Classes[Num_Setpt_Classes], class );
        UpshiftName( Setpt_Classes[Num_Setpt_Classes] );
        Num_Setpt_Classes++;
   }
}

int  AddEntry ( char *type, char *name, char *class, char *repeatable )
{
    int       entry_num;
    int       Class;
    int       Repeatable;
    int       i;
         
    for ( i = 0 ; i < Num_Exceptions ; i++ )
    {
          if ( strcmp( type, Exceptions[i].Name ) == 0 )
          {
               entry_num =  i;
               break;
          }
    }
    if ( i == Num_Exceptions ) return -1;

    for ( i = 0 ; i < Num_Classes ; i++ )
    {
          if ( strcmp( class, Class_Names[i] ) == 0 )
          {
               Class =  i;
               break;
          }
    }
    if ( i == Num_Classes ) return -2;

    for ( i = 0 ; i < Num_Repeat ; i++ )
    {
          if ( strcmp( repeatable, Repeat_Names[i] ) == 0 )
          {
               Repeatable = i;
               break;
          }
    }
    if ( i == Num_Repeat ) return -3;

    /* set up exception element name */
    DownshiftName( name );
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Name, name );

    Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Class = Class;
    Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Repeatable = Repeatable;

    /* setup default conversion routine */
    Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Conv = 0;


    /* default msg name generation */
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Msg_Name, "MSG_" );
    strcat( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Msg_Name, name );
    UpshiftName( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Msg_Name );

    /* default status msg name generation */
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Status_Msg_Name, "NO_MSG" );

    /* default Glp msg name generation */
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Hdr_Msg,  "NO_MSG" );
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Msg_Name, "NO_MSG" );

    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Dev_Code, name );
    strcat( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Dev_Code, "_dev" );
    UpshiftName ( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Dev_Code );

    Exceptions[entry_num].Num_Entries++;

    return 0;
}

int  AddSetpt ( char *type, char *name )
{
    int       entry_num;
    int       Class;
    int       Repeatable;
    int       i;
         
    for ( i = 0 ; i < Num_Exceptions ; i++ )
    {
          if ( strcmp( type, Exceptions[i].Name ) == 0 )
          {
               entry_num =  i;
               break;
          }
    }
    if ( i == Num_Exceptions ) return -1;


    /* set up exception element name */
    DownshiftName( name );
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Name, name );

    Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Class = Class;
    Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Repeatable = Repeatable;

    /* setup default conversion routine */
    Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Conv = 0;


    /* default msg name generation */
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Msg_Name, "MSG_" );
    strcat( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Msg_Name, name );
    UpshiftName( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Msg_Name );

    /* default status msg name generation */
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Status_Msg_Name, "NO_MSG" );

    /* default Glp msg name generation */
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Hdr_Msg,  "NO_MSG" );
    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Msg_Name, "NO_MSG" );

    strcpy( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Dev_Code, name );
    strcat( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Dev_Code, "_dev" );
    UpshiftName ( Exceptions[entry_num].Entries[Exceptions[entry_num].Num_Entries].Glp_Dev_Code );

    Exceptions[entry_num].Num_Entries++;

    return 0;
}

int SetMsgName ( char *exception, char *msg_name )
{

   int i,j;
   char name[ MAX_NAME_LEN ];

   strcpy( name, exception );
   DownshiftName( name );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
       for ( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
       {
            if ( strcmp( name, Exceptions[i].Entries[j].Name ) == 0 )
            {
                 strcpy( Exceptions[i].Entries[j].Msg_Name, msg_name );
                 return 0;
            }
       }
   }

   return -1;
}


int SetStatusMsgName ( char *exception, char *msg_name )
{

   int i,j;
   char name[ MAX_NAME_LEN ];

   strcpy( name, exception );
   DownshiftName( name );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
       for ( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
       {
            if ( strcmp( name, Exceptions[i].Entries[j].Name ) == 0 )
            {
                 strcpy( Exceptions[i].Entries[j].Status_Msg_Name, msg_name );
                 return 0;
            }
       }
   }

   return -1;
}



int SetConvName ( char *exception, char *conv_name )
{

   int i,j,conv;
   char name[ MAX_NAME_LEN ];

   strcpy( name, conv_name );
   UpshiftName( name );

   for ( conv = 0 ; conv < Num_Conv ; conv++ )
   {
       if ( strcmp( name, Conv_Names[ conv ] ) == 0 ) break;
   }

   if ( conv == Num_Conv ) return -2;

   strcpy( name, exception );
   DownshiftName( name );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
       for ( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
       {
            if ( strcmp( name, Exceptions[i].Entries[j].Name ) == 0 )
            {
                 Exceptions[i].Entries[j].Conv = conv;
                 return 0;
            }
       }
   }

   return -1;
}


int SetSetptClass ( char *exception, char *class_name )
{

   int i,j,class;
   char name[ MAX_NAME_LEN ];

   strcpy( name, class_name );
   UpshiftName( name );

   for ( class = 0 ; class < Num_Setpt_Classes ; class++ )
   {
       if ( strcmp( name, Setpt_Classes[ class ] ) == 0 ) break;
   }

   if ( class == Num_Setpt_Classes ) return -2;

   strcpy( name, exception );
   DownshiftName( name );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
       for ( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
       {
            if ( strcmp( name, Exceptions[i].Entries[j].Name ) == 0 )
            {
                 Exceptions[i].Entries[j].Setpt_Class = class;
                 return 0;
            }
       }
   }

   return -1;
}

int SetGlpInfo( char *exception, char *msg_no, char *dev_code )
{

   int i,j;
   char name[ MAX_NAME_LEN ];

   strcpy( name, exception );
   DownshiftName( name );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
       for ( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
       {
            if ( strcmp( name, Exceptions[i].Entries[j].Name ) == 0 )
            {
                 strcpy( Exceptions[i].Entries[j].Glp_Hdr_Msg,  msg_no );
                 UpshiftName( Exceptions[i].Entries[j].Glp_Hdr_Msg  );

                 strcpy( Exceptions[i].Entries[j].Glp_Msg_Name, dev_code );
                 UpshiftName( Exceptions[i].Entries[j].Glp_Msg_Name );

                 return 0;
            }
       }
   }

   return -1;
}



void DownshiftName ( char *str )
{
    int i;
    char c;

    i = 0;

    while ( (c = *(str+i)) != '\0' )
    {
        if (( c >= 'A' ) && ( c <= 'Z' )) 
            *(str+i) = c + ( 'a' - 'A' );
        i++;
    }
}

void UpshiftName ( char *str )
{
    int i;
    char c;

    i = 0;

    while ( (c = *(str+i)) != '\0' )
    {
        if (( c >= 'a' ) && ( c <= 'z' )) 
            *(str+i) = c - ( 'a' - 'A' );
        i++;
    }
}


void UpshiftWords( char *str )
{
    int i;
    char c;

    i = 0;

    while ( (c = *(str+i)) != '\0' )
    {
        if (( i == 0 ) || ( *(str+i-1) == '_' ))
        {
            if (( c >= 'a' ) && ( c <= 'z' )) 
            {
                 *(str+i) = c - ( 'a' - 'A' );
            }
        }
        else
        {
            if (( c >= 'A' ) && ( c <= 'Z' )) 
            {
                 *(str+i) = c + ( 'a' - 'A' );
            }
        }
        i++;
    }
}




void MakeFuncName( char *str, char * name )
{
    int i;
    char c;

    i = 0;

    while ( (c = *(name+i)) != '\0' )
    {
        if ( c == '_' )
        {
          ;  /* do nothing, skip this char */
        }
        else if (( i == 0 ) || ( *(name+i-1) == '_' ))
        {
            if (( c >= 'a' ) && ( c <= 'z' )) 
            {
                 *(str++) = c - ( 'a' - 'A' );
            }
            else
            {
                 *(str++) = c;
            }
        }
        else
        {
            if (( c >= 'A' ) && ( c <= 'Z' )) 
            {
                 *(str++) = c + ( 'a' - 'A' );
            }
            else
            {
                 *(str++) = c;
            }
        }
        i++;
    }

    *(str++) = '\0';
}



void Init( void )
{

   int i;

   for ( i = 0 ; i < MAX_EXCEPTIONS ; i++ )
   {
       Exceptions[i].Num_Entries = 0;
   }

   strcpy( Last_Entry_Name, "" );  /* use any invalid name */

   Num_Exceptions = 0;
   Num_Classes = 0;
   Num_Repeat = 0;
   Num_Conv = 0;
   Num_Setpt_Classes = 0;

   CreateConv( "NO_CONV" );         /* add the default class */
   CreateSetptClass( "NO_SETPT" );  /* add the default class */

}


void PrintExceptionClasses( void )
{
    int i;

    printf ( "typedef enum {\n" );
   
    for ( i = 0 ; i < Num_Exceptions-1 ; i++ )
    {
        printf ( "           %s_CLASS,\n", Exceptions[i].Name );
    }
    printf ( "           %s_CLASS\n", Exceptions[i].Name );

    printf ( " } EXCEPTION_CLASS;\n\n" );

}

void PrintClasses( void )
{
    int i;

    printf ( "typedef enum {\n" );
   
    for ( i = 0 ; i < Num_Classes-1 ; i++ )
    {
        printf ( "           %s,\n", Class_Names[i] );
    }
    printf ( "           %s\n", Class_Names[i] );

    printf ( " } EXCEPTION_TYPE;\n\n" );

}

void PrintEnum( void )
{
  int i,j;
  char name[MAX_NAME_LEN];

   printf( "typedef enum { \n\n" );


   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;
      strcpy( name, Exceptions[i].Name );
      UpshiftWords( name );

      printf( "\n     /*  %s */\n\n", name );


          strcpy( name, Exceptions[i].Scrolling_Title_Entry.Name );
          UpshiftName( name );
          printf( "   %s,\n\n", name );



      for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
      {
          strcpy( name, Exceptions[i].Entries[j].Name );
          UpshiftName( name );
          printf( "   %s,\n", name );
      }

   }

   printf( "   LAST_EXCEPTION_NAME  \n" );

   printf( " } EXCEPTION;\n\n" );


}



void PrintSetptEnum( void )
{
  int i,j;
  char name[MAX_NAME_LEN];

   printf( "typedef enum { \n\n" );


   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if (! Exceptions[i].Use_Setpt_Rules ) continue;
      strcpy( name, Exceptions[i].Name );
      UpshiftWords( name );

      printf( "\n     /*  %s */\n\n", name );

      for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
      {
          strcpy( name, Exceptions[i].Entries[j].Name );
          UpshiftName( name );
          printf( "   %s,\n", name );
      }

   }

   printf( "   LAST_SETPT_NAME  \n" );

   printf( " } SETPT;\n\n" );


}



void PrintDevCodeEnum( void )
{
  int i,j,dev_num;
  char name[MAX_NAME_LEN];

   printf( "typedef enum { \n\n" );

   /* do this twice, Lesley want's setpt first in dev code enum */

   dev_num = 0;

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if (! Exceptions[i].Use_Setpt_Rules ) continue;

      strcpy( name, Exceptions[i].Name );
      UpshiftWords( name );

      printf( "\n     /*  %s */\n\n", name );

      for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
      {
          strcpy( name, Exceptions[i].Entries[j].Glp_Dev_Code );
          UpshiftName( name );
          printf( "   %-30s = %4d,\n", name,dev_num );
          dev_num++;
      }

   }


   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

      strcpy( name, Exceptions[i].Name );
      UpshiftWords( name );

      printf( "\n     /*  %s */\n\n", name );

      for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
      {
          strcpy( name, Exceptions[i].Entries[j].Glp_Dev_Code );
          UpshiftName( name );
          printf( "   %-30s = %4d,\n", name,dev_num );
          dev_num++;
      }

   }

   printf( "   LAST_DEV_CODE  \n" );

   printf( " } DEV_CODE;\n\n" );


}


/* Create list of dev codes for GCRL doc */
void PrintDevCodeList( void )
{
  int i,j,dev_num;
  char name[MAX_NAME_LEN];

   printf( "<deviation_code> = \n\n" );

   /* do this twice, Lesley want's setpt first in dev code enum */

   dev_num = 1;

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if (! Exceptions[i].Use_Setpt_Rules ) continue;

      strcpy( name, Exceptions[i].Name );
      UpshiftWords( name );

      printf( "\n     /*  %s */\n\n", name );

      for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
      {
          strcpy( name, Exceptions[i].Entries[j].Glp_Dev_Code );
          UpshiftName( name );
          printf( "   %-30s = %4d,\n", name,dev_num );
          dev_num++;
      }

   }


   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

      strcpy( name, Exceptions[i].Name );
      UpshiftWords( name );

      printf( "\n     /*  %s */\n\n", name );

      for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
      {
          strcpy( name, Exceptions[i].Entries[j].Glp_Dev_Code );
          UpshiftName( name );
          printf( "   %-30s = %4d,\n", name,dev_num );
          dev_num++;
      }

   }

   printf( " } \n\n" );


}



void PrintConvEnum( void )
{
  int i,j;
  char name[MAX_NAME_LEN];

   printf( "typedef enum { \n\n" );


   for ( i = 0 ; i < Num_Conv-1 ; i++ )
   {
      strcpy( name, Conv_Names[i] );
      UpshiftName( name );
      printf( "   %s,\n", name );
   }
      strcpy( name, Conv_Names[i] );
      UpshiftName( name );
      printf( "   %s \n", name );

   printf( " } CONV_CODE;\n\n" );


}


void PrintSetptClasses( void )
{
  int i;
  char name[MAX_NAME_LEN];

   for ( i = 0 ; i < Num_Setpt_Classes; i++ )
   {
      strcpy( name, Setpt_Classes[i] );
      UpshiftName( name );
      printf( "#define %-20s %d\n", name, i );
   }

   printf( " \n\n" );
}


/* Return the number of words needed for 32-bit word
   bit-fields
*/
int GetWordCount( int num_entries )
{
   if ( num_entries % 32 == 0 )
   {
      return num_entries/32;
   }

   return num_entries/32 + 1;
}

void PrintDefines( void )
{
   int i,word_count;
   char type_position[ MAX_NAME_LEN ];
   char type_name[ MAX_NAME_LEN ];

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

      word_count = GetWordCount( Exceptions[i].Num_Entries );
      strcpy( type_position, Exceptions[i].Type_Position );

      strcpy( type_name, Exceptions[i].Name );
      UpshiftWords( type_name );

      /* Print a define for the exception type if appropriate */
      if ( strcmp( type_position, "NO_DEFINE") != 0 )
      {
         if ( strncmp( type_position, "FIRST", 5 ) == 0 )
         { 
            printf( "#define %s &%s[%1d]         \n",type_position, type_name, 0);
         }
 
         if ( strncmp( type_position, "LAST", 4 ) == 0 )
         { 
            printf( "#define %s &%s[%1d]         \n",type_position, type_name, word_count-1);
         } 
      }
   }

   printf( "                                                            \n" );

}


void PrintStruct( Entry *table, int num_entries, char *type_name )
{
      int i,j,word_count;

      j = 1;

      word_count = GetWordCount( num_entries );

      /* Define the number of bit mask words for the exception class */
      printf( "#define      %s_WORD_COUNT      %1d \n", type_name, word_count );

      /* Print the bit-field struct for each word */
      do 
      {
         printf ( "\n\ntypedef struct\n" );
         printf (      "       {\n" );

         for ( i = 32*(j-1); i < MIN(32*j,num_entries); i++ )
         {
            printf( "             unsigned %-32s :1;  /* bit %2d */\n", (table+i)->Name, 32-i%32-1 );
         } 
         if ( num_entries < 32*j )
         {
            printf( "             unsigned %-32s :%d;  /* unused bits */\n", "filler_bits", 32-num_entries%32 );
         }
         printf(       "\n       }  %s_FLAGS_WORD_%1d;\n\n", type_name, j );
         j++;
 
      } while ( j <= word_count );

      printf( "           \n" );
}



void PrintAllStruct(void)
{
   int i;

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

      PrintStruct( Exceptions[i].Entries, Exceptions[i].Num_Entries, Exceptions[i].Name );
   }

   printf( "                                                            \n" );
   printf( "   typedef struct {                                         \n" );
   printf( "             BIT32 status;   /* presence bits (1=active) */ \n" );
   printf( "             BIT32 eval;     /* ready eval bits          */ \n" );
   printf( "             BIT32 glp;      /* glp log bits             */ \n" );
   printf( "                                                            \n" );
   printf( "           } EXCEPTION_WORDS;                               \n" );
   printf( "                                                            \n" );

   printf( "                                                            \n" );
   printf( "                                                            \n" );
   printf( "   typedef struct {                                         \n" );
   printf( "             EXCEPTION_WORDS *words;                        \n" );
   printf( "             BIT32           bit_mask;                      \n" );
   printf( "             U_INT16         msg_no;                        \n" );
   printf( "             U_INT16         status_msg_no;                 \n" );
   printf( "             U_INT16         glp_hdr_msg;                   \n" );
   printf( "             U_INT16         glp_msg_no;                    \n" );
   printf( "             U_INT16         glp_dev_code;                  \n" );
   printf( "             U_INT16         exception_type;                \n" );
   printf( "             CONV_CODE       conv_code;                     \n" );
   printf( "             U_INT16         exception_no;                  \n" );
   printf( "             BIT8            repeatable;                    \n" );
   printf( "                                                            \n" );
   printf( "           } EXCEPTION_INFO_ENTRY;                          \n" );
   printf( "                                                            \n" );

   printf( "                                                            \n" );
   printf( "   typedef struct {                                         \n" );
   printf( "             U_INT16   glp_hdr_msg;                         \n" );
   printf( "             U_INT16   glp_msg_no;                          \n" );
   printf( "             U_INT16   glp_dev_code;                        \n" );
   printf( "             CONV_CODE conv_code;                           \n" );
   printf( "             BIT8      setpt_class;                         \n" );
   printf( "                                                            \n" );
   printf( "           } SETPT_INFO_ENTRY;                              \n" );
   printf( "                                                            \n" );

   printf( "                                                            \n" );
   printf( "   typedef struct {                                         \n" );
   printf( "             EXCEPTION_WORDS *words;                        \n" );
   printf( "             const BIT32     *valid_bits;                   \n" );
   printf( "             U_INT16         word_count;                    \n" );
   printf( "                                                            \n" );
   printf( "           } EXCEPTION_CLASS_INFO;                          \n" );
   printf( "                                                            \n" );

   printf( "                                                            \n" );
}

void PrintMaskExterns( void )
{
   int i,j;
   unsigned long mask;
   char name[ MAX_NAME_LEN ];

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

       strcpy( name, Exceptions[i].Name );
       UpshiftName( name );

       printf( "extern const EXCEPTION_CLASS_INFO %s_INFO;\n", name );
       printf( "extern const BIT32 %s_VALID_BITS[];\n", name );

       printf( "\n" );
   }
}

void PrintExceptionInfo( void )
{
   int i,j,k,word_count;
   unsigned long mask;
   char name[ MAX_NAME_LEN ];
   char var_name[ MAX_NAME_LEN ];

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

       strcpy( name, Exceptions[i].Name );
       UpshiftName( name );

       strcpy( var_name, Exceptions[i].Name );
       UpshiftWords( var_name );

       word_count = GetWordCount( Exceptions[i].Num_Entries );

       k = 1;      

       printf( "const EXCEPTION_CLASS_INFO %s_INFO=  \n", name );
       printf( "{\n" );

       /* Define the start of the exception array */
       printf( "   (EXCEPTION_WORDS *)%s,       \t/* exception words      */\n", var_name );

       /* Define the start of the valid bits array */
       printf( "   (const BIT32 *)%s_VALID_BITS,\t/* exception word masks */\n", name );

       /* Define the number of bit mask words for the exception class */
       printf( "   %1d,                         \t\t\t/* number of words    */\n", word_count );

       printf( "};\n" );
       printf( "\n" );

       printf( "const BIT32 %s_VALID_BITS[]=  \n", name );
       printf( "{\n" );

       do
       {
          mask = 0;
          for ( j = 32*(k-1) ; ( j < Exceptions[i].Num_Entries ) && ( j <= (32*k) ) ; j++ )
          {
             mask = (mask << 1) + 1;
          }

          /* see if this word is not filled, if so then shift over by unused bits */
          if ( mask != 0xffffffff )
          {
             mask = mask << ( 32 - Exceptions[i].Num_Entries % 32 );
          }
           
          printf( "   0x%08x,       \t\t/*  word %1d valid bits   */\n", mask, k-1 );

          k++;
       } 
       while ( k <= word_count );

       printf( "};\n" );

       printf( "\n" );
   }
}


void PrintAllocations(void)
{
   int i,num_entries;
   char type_name[ MAX_NAME_LEN ];
   char name     [ MAX_NAME_LEN ];

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

       strcpy( name,      Exceptions[i].Name );
       UpshiftWords( name );
   
       num_entries = Exceptions[i].Num_Entries;
 
       printf( "EXCEPTION_WORDS   \t%s[%1d];\n" ,name, GetWordCount( num_entries ) );

       printf( "\n" );
   }
}


void PrintArrayEntry( Entry *table, int i, char *type, int num_entries, int base_num )
{
     int num_words, num_bits;
     char name[MAX_NAME_LEN];

     strcpy( name, (table+i)->Name );

     printf( "      {                   &%s[%1d],             /* %s */\n", type, i/32, name, name );

     printf( "      /* Bit Mask   */    0x%08x,\n", 1 <<  ( 32 - (i % 32 + 1) ));
     printf( "      /*PopUp Msg   */    %s,\n",   (table+i)->Msg_Name );
     printf( "      /*Status Msg  */    %s,\n",   (table+i)->Status_Msg_Name );
     printf( "      /*GlpHdr Msg  */    %s,\n",   (table+i)->Glp_Hdr_Msg  );
     printf( "      /*GlpLog Msg  */    %s,\n",   (table+i)->Glp_Msg_Name );
     printf( "      /*GlpDevCode  */    %s,\n",   (table+i)->Glp_Dev_Code );
     printf( "      /*Type        */    %s,\n",   Class_Names[ (table+i)->Class ] );
     printf( "      /*Conv_Code   */    %s,\n",   Conv_Names[ (table+i)->Conv ] );
     printf( "      /*Except. no. */    %u,\n",   ( base_num == 0 ) ? 0 : base_num+i );
     printf( "      /*Repeatable  */    %1d\n",   (table+i)->Repeatable  );
     printf( "      },\n\n" );
}


void PrintExceptionArray( void )
{
   int i,j;
   char name[MAX_NAME_LEN];

      printf( "   const EXCEPTION_INFO_ENTRY Exception_Info[] =     \n" );
      printf( "   {                                                        \n" );
      printf( "                                                            \n" );
      printf( "                                                            \n" );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {

      if ( Exceptions[i].Use_Setpt_Rules ) continue;

        strcpy( name, Exceptions[i].Name );
        UpshiftWords( name );

        printf( " /*  %s */\n\n", name );

        PrintArrayEntry( &Exceptions[i].Scrolling_Title_Entry, 0, name, 0, 0 ); 

        for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
        {
             PrintArrayEntry( Exceptions[i].Entries, j, name, Exceptions[i].Num_Entries,
                              Exceptions[i].Base_Exception_No );
        }
   }


      printf( "   };                                                       \n" );
      printf( "                                                            \n" );
}

void PrintSetptArrayEntry( Entry *table, int i, char *type, int num_entries )
{
     char name[MAX_NAME_LEN];

     strcpy( name, (table+i)->Name );
     
     printf( "      { /*GlpHdr Msg*/      %s,        /* %s */\n", (table+i)->Glp_Hdr_Msg,   name  );
     printf( "        /*GlpLog Msg*/      %s,\n",                 (table+i)->Glp_Msg_Name );
     printf( "        /*GlpDevCode*/      %s,\n",                 (table+i)->Glp_Dev_Code );
     printf( "        /*Conv_Code */      %s,\n",                 Conv_Names[ (table+i)->Conv ] );
     printf( "        /*SetptClass*/      %s \n",                 Setpt_Classes[ (table+i)->Setpt_Class ] );
     printf( "      },\n\n" );

 
}

void PrintSetptArray( void )
{
   int i,j;
   char name[MAX_NAME_LEN];

      printf( "   const SETPT_INFO_ENTRY Setpt_Info[] =                    \n" );
      printf( "   {                                                        \n" );
      printf( "                                                            \n" );
      printf( "                                                            \n" );

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {

      if ( !Exceptions[i].Use_Setpt_Rules ) continue;

        strcpy( name, Exceptions[i].Name );
        UpshiftWords( name );

        printf( " /*  %s */\n\n", name );

        for( j = 0 ; j < Exceptions[i].Num_Entries ; j++ )
        {
             PrintSetptArrayEntry( Exceptions[i].Entries, j, name, Exceptions[i].Num_Entries );
        }
   }


      printf( "   };                                                       \n" );
      printf( "                                                            \n" );

}


 /********************************************************************** 

     M a s k   W o r d   B a s e d   F u n c t i o n s 

  **********************************************************************/

void PrintMaskWordFuncs()
{
   int i;
   char define_name[ MAX_NAME_LEN ];
   char status_name[ MAX_NAME_LEN ];
   char func_name  [ MAX_NAME_LEN ];


   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

        MakeFuncName( func_name, Exceptions[i].Name );

        strcpy( define_name, Exceptions[i].Name );
        UpshiftName( define_name );

        strcpy( status_name, Exceptions[i].Name );
        UpshiftWords( status_name );
   }

}


void PrintExterns()
{
   int i,word_count;
   char type_name[ MAX_NAME_LEN ];
   char name     [ MAX_NAME_LEN ];

   for ( i = 0 ; i < Num_Exceptions ; i++ )
   {
      if ( Exceptions[i].Use_Setpt_Rules ) continue;

       word_count = GetWordCount( Exceptions[i].Num_Entries );

       strcpy( type_name, Exceptions[i].Name );
       strcpy( name,      Exceptions[i].Name );
       UpshiftName( type_name );
       UpshiftWords( name );
    
       printf( "extern EXCEPTION_WORDS \t%s[%1d];\n",  name, word_count );

       printf( "\n" );

   }
   printf( "extern const EXCEPTION_INFO_ENTRY Exception_Info[];      \n" );
   printf( "extern const SETPT_INFO_ENTRY Setpt_Info[];      \n\n" );
}



void PrintFuncProtos()
{
  int i;
  char func_name[ MAX_NAME_LEN ];

  for ( i = 0 ; i < Num_Exceptions ; i++ )
  {
       
       MakeFuncName( func_name, Exceptions[ i ].Name );

  }

}

main (char  argc, char *argv[] )
{

   int i;
   char str[MAX_NAME_LEN];
   char elm[MAX_NAME_LEN];
   char msg[MAX_NAME_LEN];

   Init();

   yyparse();

   /* this should be in err_info.h include file */

   printf ( "cat <<@exception.h >../include/exception.h\n" );

   printf ( "/* computer generated include file */\n" );
   printf ( "#ifndef EXCEPTION_H\n" );
   printf ( "#define EXCEPTION_H\n\n" );

   PrintClasses();
   PrintExceptionClasses();

   PrintDefines();

   PrintConvEnum();

   PrintSetptClasses();

   PrintEnum();

   PrintSetptEnum();

   PrintAllStruct();

   PrintMaskExterns();

   PrintExterns();

   PrintFuncProtos();

   printf( "#endif /* EXCEPTION_H */\n" );

   printf ( "\n@exception.h\n" );

   /* begin creating the guts of the exception.c source file */

   printf ( "cat <<@exception.b >exception.b\n" );

   PrintAllocations();

   PrintExceptionInfo();

   PrintExceptionArray();

   PrintSetptArray();

   PrintMaskWordFuncs();

   printf ( "\n@exception.b\n" );

   printf ( "cat <<@dev_code.b  > dev_code.b\n" );

   printf ( "/* computer generated include file */\n" );
   printf ( "#ifndef DEV_CODE_H\n" );
   printf ( "#define DEV_CODE_H\n\n" );

   PrintDevCodeEnum();

   printf ( "\n@dev_code.b\n" );

   /* generate a list of dev codes for data comm command GCRL */

   printf ( "cat <<@dev_code.d  > dev_code.d\n" );

   printf ( "/* computer generated file for GCRL: dev_code.d */\n" );

   PrintDevCodeList();

   printf ( "\n@dev_code.d\n" );
}

